/* 
 * cms，一个基于J2EE架构内容管理系统
 * Copyright © GrayRabbit Co., Ltd. All rights reserved.
 * Department:运营department
 * 更多信息请访问：
 * http://code.google.com/p/gray-rabbit-cms/
 */
package org.grayrabbit.cms.service.dictionary.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cms.constant.DictionaryStaticValues;
import org.grayrabbit.cms.dao.dictionary.DictionaryDao;
import org.grayrabbit.cms.dao.dictionary.DictionaryTypeDao;
import org.grayrabbit.cms.entity.Dictionary;
import org.grayrabbit.cms.entity.DictionaryType;
import org.grayrabbit.cms.entity.OperLog;
import org.grayrabbit.cms.service.dictionary.DictionaryService;
import org.grayrabbit.cms.vo.dictionary.DictionaryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.grayrabbit.dao.util.Page;
import org.grayrabbit.service.impl.GenericServiceImpl;
/**
 * <b>OperLog</b>的service实现类，事务加此处：





 * @version 1.0,创建时间: 2011-05-16 14:46:47  
 */
@Service
@Transactional
public class DictionaryServiceImpl extends GenericServiceImpl implements DictionaryService {
	/**
	 * 注入dao层：
	 */
	@Autowired
	@Qualifier("dictionaryDaoImpl")
	private DictionaryDao dictionaryDao;
	@Autowired
	@Qualifier("dictionaryTypeDaoImpl")
	private DictionaryTypeDao dictionaryTypeDao;
	/**
	 * 此方法执行时为只读事务：
	 * @see DictionaryService#getOperLog(String)
	 */
	@Transactional(readOnly=true)
	public Dictionary getDictionary(final String dictionaryId){
		Dictionary dictionary = dictionaryDao.findById(dictionaryId);
		dictionaryDao.initialize(dictionary);
		return dictionary;
	}
	
	/**
	 * @see DictionaryService#delete(String)
	 */
	@Transactional
	public void delete(final Dictionary dictionary) {
		synchronized (DictionaryContext.class) {
			dictionaryDao.makeTransient(dictionary);
			DictionaryContext.UPDATE_FLAG = true;
		}
	}
	
	/**
	 * @see DictionaryService#save(OperLog)
	 */
	@Transactional
	public void save(final Dictionary dictionary) {
		synchronized (DictionaryContext.class) {
			dictionaryDao.makePersistent(dictionary);	
			DictionaryContext.UPDATE_FLAG = true;
		}
	}
	
	/**
	 * 此方法执行时为只读事务：
	 * @see DictionaryService#getPage(DictionaryBean)
	 */
	@Transactional(readOnly=true)
	public Page<Dictionary> getPage(final DictionaryBean dictionaryBean){
		Page<Dictionary> page =  new Page<Dictionary>();
		page.setTotal(dictionaryDao.count(dictionaryBean));
		page.setResult(dictionaryDao.findByQc(dictionaryDao.assembly(dictionaryBean)));
		return page;
	}

	/**
	 * 此方法执行时为只读事务：
	 * @see DictionaryService#list(Page, DictionaryBean)
	 */
	public void list(Page<Dictionary> page, DictionaryBean dictionaryBean) {
		if(page==null)
			return;
		if(page.isAutoCount()){
			page.setTotal(dictionaryDao.count(dictionaryBean));
		}
		List<Dictionary> list = dictionaryDao.findByPage(page,dictionaryBean);
		for(Dictionary item:list){
			dictionaryDao.initialize(item.getDictionaryType());
		}
		page.setResult(list);
	}
	
	/**
	 * 根据主键id列删除，批量删除OperLog
	 * @see DictionaryService#delete(String[])
	 */
	public void delete(final String[] key) {
		synchronized (DictionaryContext.class) {
			int i =0;
			for(String id : key){
				dictionaryDao.makeTransient(dictionaryDao.findById(id));
				i++;
				if(i==MAX_CLEAR)
					dictionaryDao.clear();
			}
			DictionaryContext.UPDATE_FLAG = true;
		}
		
	}
	
	/**
	 * 获取所有字典类型
	 * @return
	 */
	public List<Dictionary> getAllDictionaryList(){
		return dictionaryDao.findAll();
	}
	
	/**
	 * 根据字典类型CODE获取字典LIST
	 * @see DictionaryService#getDictionaryListByTypeCode(String)
	 */
	public List<Dictionary> getDictionaryListByTypeCode(String dictionaryTypeCode){
		fillContext();
		return DictionaryContext.getListByCode(dictionaryTypeCode);
	}
	
	/**
	 * 根据父ID获取字类
	 * @param parentId
	 * @return
	 */
	public List<Dictionary> getAllDictionaryListByParentId(String parentId){
		fillContext();
		return DictionaryContext.getListByParent(parentId);
	}
	
	public List<Dictionary> ftlFindSmsContent(){
		List<Dictionary> list = new ArrayList<Dictionary>();
		list = getDictionaryListByTypeCode(DictionaryStaticValues.BOOKING_CONTENT_TYPE_SMS);
		return list;
	}
	
	public List<Dictionary> ftlFindEmailContent(){
		List<Dictionary> list = new ArrayList<Dictionary>();
		list = getDictionaryListByTypeCode(DictionaryStaticValues.BOOKING_CONTENT_TYPE_EMAIL);
		return list;
	}
	
	/**
	 * 获取字典一级子类列表
	 * @param dicTypeCode
	 * @return
	 */
	public List<Dictionary> getParentDictionaryList(String dicTypeCode){
		fillContext();
		return DictionaryContext.getParentList(dicTypeCode);
	}
	/**
	 * 根据字典KEY获取字典对象List
	 * @param dictionaryKey
	 * @return
	 */
	public List<Dictionary> getDictionaryListDictionaryKey(String dictionaryKey, String dicTypeCode){
		return DictionaryContext.getListByParent(this.getDictionaryByDictionaryKey(dictionaryKey,dicTypeCode).getDictionaryId());
	}
	/**
	 * 根据字典KEY、类型code获取字典对象
	 * @see DictionaryService#getDictionaryByDictionaryKey(String)
	 */
	public Dictionary getDictionaryByDictionaryKey(String dictionaryKey,String dicTypeCode){
		fillContext();
		return DictionaryContext.getByDicKey(dictionaryKey,dicTypeCode);
	}
	/**
	 * 内存化数据字典
	 */
	private void fillContext(){
		if(DictionaryContext.isUpdate()){
			synchronized (DictionaryContext.class) {
				DictionaryContext.UPDATE_FLAG = false;
				DictionaryContext.remove();
				List<Dictionary> dicList = dictionaryDao.findAllByOrder();
				for(Dictionary dic:dicList){
					DictionaryContext.put(dic);
				}
			}
		}
	}
	/**
	 * 批量进行保存操作
	 */
	public void saveBatch(String dicCode,DictionaryType dicType){
		Map<String,String> map = new HashMap<String,String>();
		String[] dicList = dicCode.split("@");
		synchronized (DictionaryContext.class) {
			for(String code:dicList){
				Dictionary dic = new Dictionary();
				dic.setDictionaryType(dicType);
				String[] d = code.split("\\|");
				if(d.length==6){
					if(d[0].length()<32){
						dic.setDictionaryId(null);//insert
					}else{
						dic.setDictionaryId(d[0]);//update
					}
					dic.setDictionaryKey(d[1]);
					dic.setDictionaryValue(d[2]);
					dic.setMemo(d[3]);
					dic.setOrd(Integer.parseInt(d[4]));
					if(!StringUtils.equals("0", d[5])){//非顶级目录
						//父蓝木肯定在子蓝木保存之前
						Dictionary d2 =dictionaryDao.findById(map.get(d[5]));
						dic.setDictionary(d2);	
						if(d2.getIsLeaf().equals("1")){//还没更新是否叶子接点
							d2.setIsLeaf("0");
							dictionaryDao.updateDictionary(d2);
						}
					}else{
						Dictionary d2 = new Dictionary();
						d2.setDictionaryId("-1");
						dic.setDictionary(d2);
					}
					if(dictionaryDao.findByParentId(d[0])){
						dic.setIsLeaf("0");
					}else{
						dic.setIsLeaf("1");
					}
					if(StringUtils.isNotBlank(dic.getDictionaryId())){
						dictionaryDao.updateDictionary(dic);
					}else{
						dictionaryDao.makePersistent(dic);
					}
					map.put(d[0], dic.getDictionaryId());
				}
			}
			DictionaryContext.UPDATE_FLAG = true;
		}
	}
	
	/**
	 * 对字典数据进行批量删除
	 * @param dicDelCode
	 */
	public void deleteBatch(String dicDelCode){
		synchronized (DictionaryContext.class) {
			for(String dicId:dicDelCode.split(",")){
				Dictionary dic = new Dictionary();
				dic.setDictionaryId(dicId);
				dictionaryDao.makeTransient(dic);	
				DictionaryContext.UPDATE_FLAG = true;
			}
		}
	}
	
	public List<Dictionary>  ftlFindFirstDicsByTypeKey(String key) {
		if(StringUtils.isBlank(key)) key = DictionaryStaticValues.TAX_TYPE;
		DictionaryType type = dictionaryTypeDao.findByKey(key); 
		if(type==null) return null;
		List<Dictionary> list = dictionaryDao.findTopLevelDicByTypeId(type.getDicTypeId());
		for(Dictionary d : list){
			dictionaryDao.initialize(d.getDictionaries());
		}
		return list;
	}

	public List<Dictionary> getAreaProvinces() {
		fillContext();
		List<Dictionary> list = DictionaryContext.getParentList(DictionaryStaticValues.AREA);		
		return DictionaryContext.getListByParent(list.get(0).getDictionaryId());
	}

	/**
	 * 根据字典Value获取字典对象的Key
	 * @param dictionaryValue
	 * @return
	 */
	public String getDictionaryValue(String dictionaryValue) {
		String dictionaryKeys = dictionaryDao.findByValue(dictionaryValue);
		return dictionaryKeys;
	}

	public List<Dictionary> ftlFindSiteAreas(String areaCode) {
		fillContext();
		List<Dictionary> list = new ArrayList<Dictionary>(); 
		Dictionary d = DictionaryContext.getByDicKey(areaCode, DictionaryStaticValues.AREA);
		 
		list.add(ftlLoadDictionary(d, "市本级"));
		loadAreaSons(d, list);
		if(d.getDictionary() != null && StringUtils.isNotBlank(d.getDictionary().getDictionaryId())){
			Dictionary p  = DictionaryContext.getByDicId(d.getDictionary().getDictionaryId());
			// "100000" 中华人民共和国的代码
			if(p != null && !"100000".equals(p.getDictionaryKey()) && StringUtils.isNotBlank(p.getDictionaryValue())){
				list.add(ftlLoadDictionary(p, "省本级"));
			}
		}
		return list;
	}
	
	private Dictionary ftlLoadDictionary(Dictionary dic,String value){
		Dictionary dd = new Dictionary();
		dd.setOrd(dic.getOrd());
		dd.setMemo(dic.getMemo());
		dd.setIsLeaf(dic.getIsLeaf());
		dd.setDictionaryValue(value);
		dd.setDictionaryType(dic.getDictionaryType());
		dd.setDictionaryKey(dic.getDictionaryKey());
		dd.setDictionaryId(dic.getDictionaryId());
		dd.setDictionary(dic.getDictionary());
		dd.setDictionaries(dic.getDictionaries());
		return dd;
	}
	
	private void loadAreaSons(Dictionary d,List<Dictionary> list){
		List<Dictionary> sons = DictionaryContext.getListByParent(d.getDictionaryId());
		for(Dictionary dic :sons){
			if("县".equals(dic.getDictionaryValue().trim()) 
					|| "市辖区".equals(dic.getDictionaryValue())){
				list.addAll(DictionaryContext.getListByParent(dic.getDictionaryId()));				
			}else{
				list.add(dic);
			}
		}
	}
}